﻿using DuckEntities;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace Duck.Web
{
    public class DuckTestingService : IDuckTestingService
    {
        private DuckDbEntities context;

        public DuckTestingService()
        {
            this.context = new DuckDbEntities();
            this.context.Configuration.ProxyCreationEnabled = false;
        }

        public List<DUCK> GetAllDucks()
        {         
            try
            {
                var ducks = (from duck in this.context.DUCKs
                             select duck).ToList();
                return ducks;
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void AddNewDuck(DUCK duck)
        {
            try
            {
                this.context.DUCKs.Add(duck);
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void DeleteDuck(DUCK duck)
        {
            try
            {
                //first delete all the references of this duck from the DUCKRAFT table
                var dckrft = (from duckraft in this.context.DUCKRAFTs
                              where duck.DuckID == duckraft.DuckId
                              select duckraft.RaftID).ToList();
                foreach (int duckraftid in dckrft)
                {
                    DUCKRAFT dr = this.context.DUCKRAFTs.Find(duckraftid);
                    this.context.DUCKRAFTs.Remove(dr);
                }
                //now delete de duck entry from the DUCK table
                DUCK dck = this.context.DUCKs.Find(duck.DuckID);
                this.context.DUCKs.Remove(dck);
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void UpdateDuck(DUCK duck)
        {
            try
            {
                DUCK dck = this.context.DUCKs.Find(duck.DuckID);
                if(dck.Name != duck.Name)
                    dck.Name = duck.Name;
                if(dck.Color != duck.Color)
                    dck.Color = duck.Color;
                if(dck.About != dck.About)
                    dck.About = duck.About;
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public List<RAFT> GetAllRafts()
        {
            try
            {
                var rafts = (from raft in this.context.RAFTs
                             select raft).ToList();
                return rafts;
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public List<DUCK> GetAllDucksRaft(RAFT raft)
        {
            try
            {
                var duckrIds = (from duckraft in this.context.DUCKRAFTs
                                where raft.GroupID == duckraft.GroupID
                                select duckraft.DuckId).ToList();
                var ducks = (from duck in this.context.DUCKs
                             where duckrIds.Contains(duck.DuckID)
                             select duck).ToList();
                return ducks;
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void AddNewRaft(RAFT raft)
        {
            try
            {
                this.context.RAFTs.Add(raft);
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void UpdateRaft(RAFT raft)
        {
            try
            {
                RAFT rft = this.context.RAFTs.Find(raft.GroupID);
                if (rft.Name != raft.Name)
                    rft.Name = raft.Name;
                if (rft.Description != raft.Description)
                    rft.Description = raft.Description;
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void DeleteRaft(RAFT raft)
        {
            try
            {
                //first delete all the references of this raft in the DUCKRAFT table
                var dckrft = (from duckraft in this.context.DUCKRAFTs
                              where raft.GroupID == duckraft.GroupID
                              select duckraft.RaftID).ToList();
                foreach (int duckraftid in dckrft)
                {
                    DUCKRAFT dr = this.context.DUCKRAFTs.Find(duckraftid);
                    this.context.DUCKRAFTs.Remove(dr);
                }
                //now delete the raft entry from the RAFT table
                RAFT rft = this.context.RAFTs.Find(raft.GroupID);
                this.context.RAFTs.Remove(rft);
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        public void DeleteDuckFromRaft(DUCK duck, RAFT raft)
        {
            var dckrft = (from duckraft in this.context.DUCKRAFTs
                          where raft.GroupID == duckraft.GroupID && duck.DuckID == duckraft.DuckId
                          select duckraft.RaftID).ToList();
            foreach (int duckraftid in dckrft)
            {
                DUCKRAFT dr = this.context.DUCKRAFTs.Find(duckraftid);
                this.context.DUCKRAFTs.Remove(dr);
            }
            this.context.SaveChanges();
        }

        public void AddDuckToRaft(DUCKRAFT duckraft)
        {
            try
            {
                this.context.DUCKRAFTs.Add(duckraft);
                this.context.SaveChanges();
            }
            catch (DbException e)
            {
                throw new Exception("" + e.Message);
            }
        }

        /// <summary>
        /// NEW METHODS TO IMPLEMENT FOR THE CRUD OPERATIONS ON GROUPS OF DUCKS
        /// </summary>
        /// <returns></returns>                

        public List<RAFT> GetAllDuckRafts(DUCK duck)
        {
            throw new NotImplementedException();
        }           

        
    }
}
